package algorithms.leaning.class17;

import common.util.MyUtil;

/**
 * 打印n层汉诺塔从最左边移动到最右边的全部过程
 * <p>
 * 初级版，使用6个过程
 *
 * @author guichang
 * @date 2021/6/16
 */

@SuppressWarnings("all")
public class Code2_递归_汉诺塔1 {

    public static void main(String[] args) {
        hanoi(3);
    }

    /**
     * 汉诺塔
     */
    public static void hanoi(int n) {
        // n个数整个从左到右
        left2Right(n);
    }

    /**
     * n个数从左到右
     */
    private static void left2Right(int n) {
        if (n == 1) {
            MyUtil.printf("移动{}从{}到{}", n, "左", "右");
            return;
        }
        // n-1个数从左到中
        left2Mid(n - 1);
        MyUtil.printf("移动{}从{}到{}", n, "左", "右");
        // n-1个数从中到右
        mid2Right(n - 1);
    }

    /**
     * n个数从左到中
     */
    private static void left2Mid(int n) {
        if (n == 1) {
            MyUtil.printf("移动{}从{}到{}", n, "左", "中");
            return;
        }
        // n-1个数从左到右
        left2Right(n - 1);
        MyUtil.printf("移动{}从{}到{}", n, "左", "中");
        // n-1个数从右到中
        right2Mid(n - 1);
    }

    /**
     * n个数从中到左
     */
    private static void mid2Left(int n) {
        if (n == 1) {
            MyUtil.printf("移动{}从{}到{}", n, "中", "左");
            return;
        }
        // n-1个数从中到右
        mid2Right(n - 1);
        MyUtil.printf("移动{}从{}到{}", n, "中", "左");
        // n-1个数从右到左
        right2Left(n - 1);
    }

    /**
     * n个数从中到右
     */
    private static void mid2Right(int n) {
        if (n == 1) {
            MyUtil.printf("移动{}从{}到{}", n, "中", "右");
            return;
        }
        // n-1个数从中到左
        mid2Left(n - 1);
        MyUtil.printf("移动{}从{}到{}", n, "中", "右");
        // n-1个数从左到右
        left2Right(n - 1);
    }

    /**
     * n个数从右到左
     */
    private static void right2Left(int n) {
        if (n == 1) {
            MyUtil.printf("移动{}从{}到{}", n, "右", "左");
            return;
        }
        // n-1个数从右到中
        right2Mid(n - 1);
        MyUtil.printf("移动{}从{}到{}", n, "右", "左");
        // n-1个数从中到左
        mid2Left(n - 1);
    }

    /**
     * n个数从右到中
     */
    private static void right2Mid(int n) {
        if (n == 1) {
            MyUtil.printf("移动{}从{}到{}", n, "右", "中");
            return;
        }
        // n-1个数从右到左
        right2Left(n - 1);
        MyUtil.printf("移动{}从{}到{}", n, "右", "中");
        // n-1个数从中到左
        left2Mid(n - 1);
    }

}